#include "caesar.h"

#define ENCRYPTED_CHAR(offset, ch, increment, alpha_len) (offset + (ch + increment - offset) % alpha_len)
#define DECRYPTED_CHAR(offset, ch, increment, alpha_len) (offset + (ch + (alpha_len - increment) - offset) % alpha_len)
#define ALPHA_LEN 26
#define ALPHA_START_UPPERCASE 'A'
#define ALPHA_START_LOWERCASE 'a'

void caesar_encrypt_cstr(char *cstr)
{
    for(char *c = cstr; *c; ++c)
    {
        *c = caesar_encrypt_char(*c);
    }
}

void caesar_decrypt_cstr(char *cstr)
{
    for(char *c = cstr; *c; ++c)
    {
        *c = caesar_decrypt_char(*c);
    }
}

int caesar_encrypt_char(int c)
{
    if(islower(c))
        return ENCRYPTED_CHAR(ALPHA_START_LOWERCASE, c, 3, ALPHA_LEN);
    else if(isupper(c))
        return ENCRYPTED_CHAR(ALPHA_START_UPPERCASE, c, 3, ALPHA_LEN);
    return c;
}

int caesar_decrypt_char(int c)
{
    if(islower(c))
        return DECRYPTED_CHAR(ALPHA_START_LOWERCASE, c, 3, ALPHA_LEN);
    else if(isupper(c))
        return DECRYPTED_CHAR(ALPHA_START_UPPERCASE, c, 3, ALPHA_LEN);
    return c;
}

void caesar_stdin_mode(void)
{
    int c;
    while((c = getchar()) != EOF)
    {
        putchar(caesar_encrypt_char(c));
    }
}
